﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace Skyhook.Isometry
{
    internal static class CoordinatesConverter
    {
        static float WorldTileWidth = 64.0f;
        static float WorldTileHeight = 32.0f;

        const float IsoZAxisRotation = 45.0f * 2 * (float)Math.PI / 360.0f;

        static Matrix WorldToScreen;
        static Matrix ScreenToWorld;

        private static void SetupWorldMatrix()
        {
            WorldToScreen = new Matrix();
            WorldToScreen = Matrix.CreateRotationZ(IsoZAxisRotation);
            WorldToScreen *= Matrix.CreateScale(1, (float)(WorldTileHeight / Math.Sqrt(2.0)), 1);
            WorldToScreen *= Matrix.CreateScale((float)(WorldTileWidth / Math.Sqrt(2.0)), 1, 1);

            ScreenToWorld = new Matrix();
            ScreenToWorld = Matrix.CreateScale(1.0f / (float)(WorldTileWidth / Math.Sqrt(2.0)), 1, 1);
            ScreenToWorld *= Matrix.CreateScale(1, 1.0f / (float)(WorldTileHeight / Math.Sqrt(2.0)), 1);
            ScreenToWorld *= Matrix.CreateRotationZ(-IsoZAxisRotation);
        }

        static CoordinatesConverter()
        {
            SetupWorldMatrix();
        }

        public static void SetTileSize(float width, float height)
        {
            WorldTileWidth = width;
            WorldTileHeight = height;
            SetupWorldMatrix();
        }

        public static Matrix WorldToScreenMatrix
        {
            get
            {
                return WorldToScreen;
            }
        }

        public static Matrix ScreenToWorldMatrix
        {
            get
            {
                return ScreenToWorld;
            }
        }

        public static Vector2 ConvertScreenToWorld(int x, int y)
        {
            Vector2 result = new Vector2();
            Vector4 landcoords = new Vector4(x, y, 0, 1);
            landcoords = Vector4.Transform(landcoords, ScreenToWorld);
            result.X = landcoords.X;
            result.Y = landcoords.Y;
            return result;
        }
        public static Point ConvertScreenToWorldTiles(int x, int y)
        {
            Vector2 landpos = ConvertScreenToWorld(x, y);
            Point result = new Point();

            result.X = (int)(landpos.X);
            result.Y = (int)(landpos.Y);

            if (landpos.X < 0)
            {
                result.X = result.X - 1;
            }
            if (landpos.Y < 0)
            {
                result.Y = result.Y - 1;
            }
            return result;
        }

        public static Point ConvertWorldToScreen(float x, float y)
        {
            Point result = new Point();
            Vector4 landcoords = new Vector4(x, y, 0, 1);
            landcoords = Vector4.Transform(landcoords, WorldToScreen);
            //result.X = (int)landcoords.X;
            //result.Y = (int)landcoords.Y;
            result.X = (int)Math.Round(landcoords.X);
            result.Y = (int)Math.Round(landcoords.Y);
            return result;
        }
    }
}
